import { Checkbox, Space, Tag, message, Button } from 'antd';
import {
  ModalForm,
  ProFormSelect
} from '@ant-design/pro-form';
import React, { useEffect, useRef, useState } from 'react';

import type { ActionType } from '@ant-design/pro-table';
import {
  getApiPermissionOptions as GetPermissionOptions
} from '@/services/furion-cms/permission';
import type { ModalProps } from 'antd';
import ProDescriptions from '@ant-design/pro-descriptions';
import type { ProFormInstance } from '@ant-design/pro-form';
import ProTable from '@ant-design/pro-table';
import { putApiRoleByIdConfigre as UpdateConfigre } from '@/services/furion-cms/role';
import { useIntl } from 'umi';
import { CloseOutlined } from '@ant-design/icons';

interface RoleConfigureProps {
  modalVisible?: boolean;
  recored?: API.RoleConfigureDetailDto;
  onVisibleChange: (visit: boolean) => void;
  modalProps?: Omit<ModalProps, 'visible'>;
}

const RoleConfigure: React.FC<RoleConfigureProps> = (props) => {
  const { modalVisible, onVisibleChange, modalProps, recored } = props;
  /**
     * @en-US International configuration
     * @zh-CN 国际化配置
     * */
  const intl = useIntl();

  const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]);
  const [expandedRowKeys, setExpandedRowKeys] = useState<string[]>([]);
  const [operateDepends, setOperateDepends] = useState<string[]>([]);
  const [checkStrictly, setCheckStrictly] = useState<boolean>(true);

  // 数据源
  const [permissionData, setPermissionData] = useState<API.PermissionOptionsDto[]>();
  const [loading, setLoading] = useState<boolean>(true);

  const [configureItems, updateConfigureItems] = useState<string[]>([]);

  // 当操作依赖变化时进行与selectedRowKeys合并
  useEffect(() => {
    setSelectedRowKeys(Array.from(new Set([...selectedRowKeys, ...operateDepends])));
  }, [operateDepends]);

  const actionRef = useRef<ActionType>();
  // 绑定一个 ProFormInstance 实例
  const formRef = useRef<ProFormInstance<API.RoleConfigureDetailDto>>();

  const finishHandle = async () => {
    console.log('finishHandle-data', configureItems);
    return UpdateConfigre({ id: recored!.id! }, configureItems)
      .then(() => {
        message.success('角色配置保存成功')
        return true;
      });
  }

  const handlerFormPermission = (values: any[]) => {
    return Array.from(new Set(values.flat()));
  }

  /**
   * 递归获取权限操作列表
   * @param children 子数据集合
   * @param key 填充key前缀
   * @param isEmpty 是否清空
   * @returns 
   */
  const getPermissionOperateList = (children?: API.PermissionOptionsDto[], key?: string, isEmpty?: boolean) => {
    let resultValues: any;
    children?.forEach(f => {
      if (key) {
        resultValues = {
          ...resultValues ?? {},
          [`${key}${f.code}`]: isEmpty ? [] : f.operateList?.map(o => o.code),
          ...getPermissionOperateList(f.children, key, isEmpty) ?? {}
        }
      }
      else {
        resultValues = [
          ...resultValues ?? [],
          ...f.operateList ?? [],
          ...getPermissionOperateList(f.children, key, isEmpty) ?? []
        ]
      }
    });
    return resultValues;
  }

  const handlerConfigureItemUpdate = () => {
    // 先保存之前的数据
    const formValues = formRef.current?.getFieldFormatValue?.();
    let formResults: string[] = [];
    for (const k in formValues) {
      if (k.includes(`multiple_`)) {
        formResults = [...formResults, ...handlerFormPermission(formValues[k])];
      }
    }
    const currentSelected: string[] = selectedRowKeys;

    updateConfigureItems(Array.from(new Set([
      ...formResults,
      ...currentSelected
    ])))
  }

  const handlerPermissionData = (data: API.PermissionOptionsDto[], selectedValues: string[]) => {
    // 找到当前展开的行
    const expandedKeys = data.reduce((pre: string[], cur) => {
      // 递归处理
      const recursionHandler = (entity: API.PermissionOptionsDto, parentCode?: string[]) => {
        if (entity.children?.some(x => selectedValues.includes(x.code!))) {
          pre.push(entity.code!);
          parentCode?.forEach(p => pre.push(p));
        }
        entity.children?.forEach(f => {
          recursionHandler(f, [...parentCode ?? [], entity.code!]);
        });
      }
      recursionHandler(cur);

      return Array.from(new Set(pre));

    }, []) ?? [];

    /**
     * 找到选中的行
     * 当前菜单层级最多支持3级,多于3级将不再做处理
     */
    const selectedKeys = data.reduce((pre: string[], cur) => {
      // 递归处理
      const recursionHandler = (entity: API.PermissionOptionsDto) => {
        const items = entity.children?.filter(t => selectedValues.includes(t.code!));
        items?.forEach(f => pre.push(f.code!));
        entity.children?.forEach(f => {
          recursionHandler(f);
        })
      };
      recursionHandler(cur);

      return Array.from(new Set(pre));
    }, []) ?? [];

    setExpandedRowKeys(expandedKeys);
    setSelectedRowKeys(selectedKeys);
    console.log('handlerPermissionData-result', expandedKeys, selectedKeys)
  }

  const getPermissionModuleList = (data?: API.PermissionOptionsDto[]) => {
    let resultValues: string[] = [];
    data?.forEach(f => {
      resultValues = [...resultValues, f.code!, ...getPermissionModuleList(f.children)]
    })
    return resultValues;
  }

  const handlerSelectedAll = (data?: API.PermissionOptionsDto[]) => {
    // 获取并设置权限操作列表
    const setValues = getPermissionOperateList(data, `multiple_`);
    formRef.current?.setFieldsValue(setValues);
    // 获取并设置表格行选中行
    const rowSelectedList = getPermissionModuleList(data);
    setSelectedRowKeys(Array.from(new Set([...rowSelectedList, ...selectedRowKeys])))

    console.log('handlerSelectedAll', data, setValues);
    handlerConfigureItemUpdate();
  }

  const handlerClearSelected = (data?: API.PermissionOptionsDto[]) => {
    const setValues = getPermissionOperateList(data, `multiple_`, true);

    formRef.current?.setFieldsValue(setValues);
    // 获取并设置表格行选中行
    const rowSelectedList = getPermissionModuleList(data);

    setSelectedRowKeys(selectedRowKeys.filter(t => !rowSelectedList.includes(t)))
    console.log('handlerClearSelected', data, setValues);
    handlerConfigureItemUpdate();
  }

  const handlerSelectedTableAll = (e: any) => {
    const { checked } = e.target;
    const datas = permissionData?.flatMap(m => m.children!);
    const setValues = getPermissionOperateList(datas, "multiple_", !checked);
    formRef.current?.setFieldsValue(setValues);

    // 获取并设置表格行选中行
    const rowSelectedList = getPermissionModuleList(datas);

    setSelectedRowKeys(checked ? Array.from(new Set([...rowSelectedList, ...selectedRowKeys])) : [])

    console.log('handlerSelectedTableAll', checked, setValues);
    handlerConfigureItemUpdate();
  }

  // 数据加载
  useEffect(() => {
    if (modalVisible && recored) {
      setLoading(true);
      (async () => {
        try {
          const { data } = await GetPermissionOptions();

          // 先设置数据
          updateConfigureItems([]);
          setPermissionData(data);
          handlerPermissionData(data!, recored?.permissions ?? []);
        } catch { }
      })();
      setLoading(false);
      setCheckStrictly(false);
    }

  }, [modalVisible, recored]);// eslint-disable-line react-hooks/exhaustive-deps

  useEffect(() => handlerConfigureItemUpdate(), [selectedRowKeys, expandedRowKeys, permissionData]); // eslint-disable-line react-hooks/exhaustive-deps

  return (
    <ModalForm<API.RoleConfigureDetailDto>
      modalProps={{
        destroyOnClose: true,
        width: 800,
        maskClosable: false,
        ...modalProps
      }}
      visible={modalVisible}
      formRef={formRef}
      initialValues={recored}
      onFinish={finishHandle}
      onVisibleChange={onVisibleChange}
      onFieldsChange={() => handlerConfigureItemUpdate()}
    >
      <ProDescriptions<API.RoleConfigureDetailDto> column={2}
        dataSource={recored}
        title="角色配置"
        tooltip="配置角色的模块权限"
        extra={<Button type="text" icon={<CloseOutlined />} onClick={() => onVisibleChange(false)} />}
        columns={[
          {
            title: intl.formatMessage({
              id: 'pages.role.name',
              defaultMessage: '名称'
            }),
            dataIndex: 'name',
            render: (_, entity) => {
              return <Space>
                <span>{entity.name}</span>
                {entity.hasSeed && <Tag color="magenta">内置</Tag>}
                {entity.isDefault && <Tag color="blue">默认</Tag>}
              </Space>;
            }
          },
          {
            title: intl.formatMessage({
              id: 'pages.role.createdTime',
              defaultMessage: '创建时间'
            }),
            dataIndex: 'createdTime',
            valueType: "dateTime"
          },
          {
            title: intl.formatMessage({
              id: 'pages.role.description',
              defaultMessage: '描述'
            }),
            dataIndex: 'description',
            span: 2
          }
        ]}
      />
      <ProTable<API.PermissionOptionsDto>
        rowKey="code"
        toolBarRender={false}
        actionRef={actionRef}
        search={false}
        loading={loading}
        rowSelection={{
          checkStrictly: checkStrictly,
          selectedRowKeys: selectedRowKeys,
          onChange: (selectedKeys) => {
            setSelectedRowKeys(selectedKeys as string[]);
          },
        }}
        scroll={{
          scrollToFirstRowOnChange: true,
          y: 330
        }}
        tableAlertRender={false}
        columns={[
          {
            title: intl.formatMessage({
              id: 'pages.role.configure.module.name',
              defaultMessage: '名称'
            }),
            dataIndex: 'name',
          },
          {
            title: (<>
              {intl.formatMessage({
                id: 'pages.role.configure.module.operate',
                defaultMessage: '功能列表'
              })}
              <Checkbox key="selectedAll" style={{ float: 'right' }} onChange={handlerSelectedTableAll}>授予所有权限</Checkbox>
            </>),
            dataIndex: 'operateList',
            width: 450,
            render: (_: any, entity: API.PermissionOptionsDto) => {
              const optionData: API.PermissionDto[] = entity.operateList ?? [];
              if (optionData.length) {
                const operateList = optionData.map(({ name, code }) => ({ label: name!, value: code! }));
                const initialValue = optionData.filter(o => recored?.permissions?.includes(o.code!)).map(i => i.code);
                return <ProFormSelect
                  name={`multiple_${entity.code}`}
                  options={[...operateList]}
                  initialValue={initialValue}
                  fieldProps={{
                    mode: "multiple",
                    allowClear: true,
                    style: { width: '100%' },
                    showArrow: true,
                    maxTagCount: 'responsive' as const,
                    onChange: (values) => {
                      // if (values.length) {
                      //   setSelectedRowKeys(Array.from(new Set([...selectedRowKeys, entity.code!])));
                      // }

                      if (values.length) {
                        setOperateDepends(Array.from(new Set([...operateDepends, entity.code!])));
                      }
                    },
                    placeholder: '点击配置允许的使用的功能'
                  }}
                  noStyle={true}
                />
              }
              else {
                const childrenOptions = getPermissionOperateList(entity.children);
                if (childrenOptions?.length) {
                  const formValues = formRef.current?.getFieldFormatValue?.();
                  const recursionOptions = (children?: API.PermissionOptionsDto[]) => {
                    let values: string[] = [];
                    children?.forEach(f => {
                      values = [
                        ...values,
                        ...formValues?.[`multiple_${f.code}`] ?? [],
                        ...recursionOptions(f.children) ?? []
                      ]
                    });
                    return values;
                  }
                  const selectOptions = recursionOptions(entity.children);
                  // 当存在已选项才会显示
                  if (selectOptions?.length) {
                    return <>
                      <span style={{ color: '#909399' }}>已选择 {selectOptions?.length} 项 / 总共 {childrenOptions?.length} 项</span>
                      <Space size={14} style={{
                        float: 'right'
                      }}>
                        <a onClick={() => handlerSelectedAll(entity.children)}>全选</a>
                        <a onClick={() => handlerClearSelected(entity.children)}>清除</a>
                      </Space>
                    </>
                  }
                }
                return;
              }
            }
          },
        ]}
        dataSource={permissionData}
        pagination={false}
        expandable={{
          expandedRowKeys: expandedRowKeys,
          onExpandedRowsChange: (expandedKeys) => {
            setExpandedRowKeys(expandedKeys as string[])
          }
        }}
      />
    </ModalForm>
  )
}

export default RoleConfigure;
